package tuan.utils;

import java.util.*;

import org.w3c.dom.Node;

import tuan.filter.AllowdTagFilter;
import tuan.filter.NotAllowdParentTagFilter;
import tuan.filter.TextLengthFiltter;
import tuan.filter.TravelFilterChain;

public class NodeUtil {
	/**
	 * 对table中的节点进行排序,使得文本连续,主要用于主体识别
	 * 
	 * @param nodeList
	 * @return
	 */
	public static List<Node> ReOrderNodeByTable(List<Node> nodeList) {
		if (nodeList == null) {
			return null;
		}

		List<Node> newNodeList = new ArrayList<Node>();
		Iterator<Node> iter = nodeList.iterator();
		Node currentTrNode = null;
		Node currentTdNode = null;

		ArrayList<ArrayList<ArrayList<Node>>> table = new ArrayList<ArrayList<ArrayList<Node>>>();
		ArrayList<ArrayList<Node>> row = new ArrayList<ArrayList<Node>>();
		ArrayList<Node> col = new ArrayList<Node>();

		while (iter.hasNext()) {
			Node node = iter.next();
			Node trNode = getTrNode(node);
			Node tdNode = getTdNode(node);
			if (trNode != null && tdNode != null) {
				if (!trNode.equals(currentTrNode)) {
					row = new ArrayList<ArrayList<Node>>();
					table.add(row);
					currentTrNode = trNode;
				}
				if (!tdNode.equals(currentTdNode)) {
					col = new ArrayList<Node>();
					row.add(col);
					currentTdNode = tdNode;
				}
				col.add(node);
			} else {
				if (getTableNode(node) != null) {
					newNodeList.add(node);
					continue;
				}
				int i = 0;
				while (true) {
					boolean stop = true;
					for (ArrayList<ArrayList<Node>> rowTmp : table) {
						if (rowTmp.size() > i) {
							ArrayList<Node> colTmp = rowTmp.get(i);
							for (Node nodeTmp : colTmp) {
								newNodeList.add(nodeTmp);
							}
							stop = false;
						}
					}
					i++;
					if (stop) {
						break;
					}
				}

				table.clear();
				currentTrNode = null;
				currentTdNode = null;
				newNodeList.add(node);
			}
		}
		int i = 0;
		while (true) {
			boolean stop = true;
			for (ArrayList<ArrayList<Node>> rowTmp : table) {
				if (rowTmp.size() > i) {
					ArrayList<Node> colTmp = rowTmp.get(i);
					for (Node nodeTmp : colTmp) {
						newNodeList.add(nodeTmp);
					}
					stop = false;
				}
			}
			i++;
			if (stop) {
				break;
			}
		}
		return newNodeList;

	}

	/**
	 * 获取得分最高的节点
	 * 
	 * @param textNodeList
	 * @return
	 */
	public static Node getMaxScoreNode(List<Node> textNodeList) {

		if (textNodeList == null) {
			return null;
		}

		Node maxNode = null;
		double maxScore = 0.0;
		for (Node node : textNodeList) {
			if (node.getUserData("score") == null) {
				continue;
			}
			double score = (Double) node.getUserData("score");
			if (maxNode == null || score > maxScore) {
				maxScore = score;
				maxNode = node;
			}
		}
		return maxNode;
	}

	/**
	 * 获取节点集文本，对于相邻的数字节点，用空格分开
	 * 
	 * @param nodeList
	 * @return
	 */
	public static String getText(List<Node> nodeList) {
		Iterator<Node> iter = nodeList.iterator();
		String text = "";
		while (iter.hasNext()) {
			Node textNode = iter.next();
			String nodeText = StringUtil.getPureText(textNode.getTextContent());
			nodeText = nodeText.replaceAll("[ \\s¥￥元:：]*", "");
			text += nodeText;
			if (nodeText.length() > 0) {
				char ch = nodeText.charAt(nodeText.length() - 1);
				if (ch >= '0' && ch <= '9') {
					text += " ";
				}
			}
		}
		return text;
	}

	/**
	 * 打印节点得分
	 * 
	 * @param textNodeList
	 */
	public static void printScore(List<Node> textNodeList) {
		if (textNodeList == null) {
			return;
		}
		for (Node node : textNodeList) {
			if (node.getUserData("score") != null) {
				System.out.println("socre:" + node.getUserData("score") + ",text:" + node.getTextContent().trim());
			} else {
				System.out.println("socre:null,text:" + node.getTextContent().trim());
			}
		}
	}

	/**
	 * 获取正文类文本
	 * 
	 * @param contentNode
	 * @return
	 * @throws Exception
	 */
	public static String getContent(Node contentNode) throws Exception {
		TravelFilterChain travelChain = new TravelFilterChain();
		travelChain.addFilter(new AllowdTagFilter(new String[] { "#text" }));
		travelChain.addFilter(new NotAllowdParentTagFilter(new String[] { "SCRIPT" }));
		travelChain.addFilter(new TextLengthFiltter(0, ">"));
		DomUtil.postOrderTree(contentNode, contentNode, null, travelChain);
		List<Node> nodeList = travelChain.getNodeList();
		Iterator<Node> iter = nodeList.iterator();

		Node lastNode = null;
		Node node = null;
		String contentText = "";
		while (iter.hasNext()) {
			node = iter.next();
			if (lastNode == null) {
				contentText += node.getTextContent().trim();
			} else {
				Node parentNode = DomUtil.getMinComParrent(Arrays.asList(lastNode, node));
				String tagName = parentNode.getNodeName();
				if (parentNode != null && tagName.equals("P") || tagName.equals("LI") || tagName.equals("SPAN") || tagName.equals("TR") || tagName.equals("TH")) {
					contentText += node.getTextContent().trim();
				} else if (tagName.equals("TD")) {
					contentText += "&nbsp;" + node.getTextContent().trim();
				} else {
					contentText += "<br>" + node.getTextContent().trim();
				}				 
			}
			lastNode = node;
		}
		return contentText;
	}

	static Node getTdNode(Node node) {
		while (node != null && !node.getNodeName().equals("TD") && !node.getNodeName().equals("TH")) {
			node = node.getParentNode();
		}
		return node;
	}

	static Node getTrNode(Node node) {
		while (node != null && !node.getNodeName().equals("TR")) {
			node = node.getParentNode();
		}
		return node;
	}

	static Node getTableNode(Node node) {
		while (node != null && !node.getNodeName().equals("TABLE")) {
			node = node.getParentNode();
		}
		return node;
	}

	public static Node getNextNode(Node node) {
		while (node != null && node.getNextSibling() == null) {
			node = node.getParentNode();
		}
		return node != null ? node.getNextSibling() : null;
	}

	static void print(Object o) {
		System.out.println(o);
	}
}
